<script setup lang="tsx">
import type { Rule } from 'ant-design-vue/es/form';

import type { UnwrapRef } from 'vue';

import type { FieldVO, SceneVO } from '#/api/config/search/model';
import type { DictData } from '#/api/system/dict/dict-data-model';

import { computed, h, markRaw, onMounted, reactive, ref, toRaw } from 'vue';
import { useRoute } from 'vue-router';

import { useVbenModal } from '@vben/common-ui';
import { DictEnum } from '@vben/constants';
import { VbenIcon } from '@vben/icons';
import { useUserStore } from '@vben/stores';
import { buildUUID, cloneDeep, getPopupContainer } from '@vben/utils';

import { CloseOutlined } from '@ant-design/icons-vue';
import {
  Alert,
  Badge,
  Button,
  Checkbox,
  DropdownButton,
  Empty,
  Form,
  FormItem,
  Input,
  Menu,
  MenuItem,
  Popconfirm,
  Tooltip,
} from 'ant-design-vue';

import { useVbenForm } from '#/adapter/form';
import {
  fieldList,
  sceneAdd,
  sceneList,
  sceneRemove,
} from '#/api/config/search';
import { dictDataInfo } from '#/api/system/dict/dict-data';
import { defaultFormValueGetter, useBeforeCloseDiff } from '#/utils/popup';

import ConditionFilter from './condition-filter.vue';

interface Props {
  filterApi?: any;
  showBadge?: boolean;
}

interface FilterItem {
  fieldName: null | string;
  condition: null | string;
  value: null | string;
  exposed: boolean;

  [property: string]: any;
}

const props = withDefaults(defineProps<Props>(), {
  showBadge: false,
  filterApi: undefined,
});

const route = useRoute();
const pageName = computed(() => {
  return route.meta.title;
});

const userStore = useUserStore();
const userId = computed(() => {
  return userStore.userInfo?.userId || '0';
});

const title = computed(() => {
  // return currTemplate.value?.name
  //   ? `高级筛选（场景：${currTemplate.value.name}）`
  //   : `高级筛选`;
  return '高级筛选';
});

const [BasicForm, formApi] = useVbenForm({
  schema: [
    {
      label: '高级筛选',
      fieldName: 'list',
      component: 'Select',
      // disabledOnChangeListener: false,
      dependencies: {
        show: () => false,
        triggerFields: [''],
      },
      defaultValue: [],
    },
  ],
  showDefaultActions: false,
});

const { onBeforeClose, markInitialized, resetInitialized } = useBeforeCloseDiff(
  {
    initializedGetter: defaultFormValueGetter(formApi),
    currentGetter: defaultFormValueGetter(formApi),
  },
);

const show = ref(false);
const list = ref<FilterItem[]>([]);
const listCache = ref<FilterItem[]>([]);
const validateFail = ref(false);

interface TemplateForm {
  saveAs: boolean;
  name: string;
}

const templateFormRef = ref();
const templateForm: UnwrapRef<TemplateForm> = reactive({
  saveAs: false,
  name: '',
});
const templateFormRules: Record<string, Rule[]> = {
  name: [{ required: true, message: '请填写场景名称', trigger: 'change' }],
};
const currTemplate = ref<SceneVO>();

const [BasicModal, modalApi] = useVbenModal({
  fullscreenButton: false,
  onBeforeClose,
  // onCancel: handleCancel,
  onClosed: handleClosed,
  onConfirm: handleConfirm,
  onOpenChange: async (isOpen) => {
    if (!isOpen) {
      return null;
    }

    // listCache.value = [...list.value];
    // list.value = cloneDeep(listCache.value);
    list.value = listCache.value;

    // const listValue = await formApi.getValues();
    console.log(toRaw(list.value));
    console.log(toRaw(listCache.value));

    await markInitialized();
    modalApi.modalLoading(false);
  },
});

const filterCount = ref(0);

function handleFilterClick() {
  modalApi.open();
  console.log(props.filterApi);
}

// async function handleCancel() {
//   list.value = [...listCache.value];
//   modalApi.close();
//   await formApi.setValues({ list: listCache.value });
// }

async function handleClosed() {
  templateFormRef.value?.resetFields();
  // list.value = list.value.filter((v) => v.fieldName && v.condition && v.value);
  list.value = list.value.filter((v) => v.fieldName && v.condition);
  validateFail.value = false;
  resetInitialized();
}

// 确认筛选
async function handleConfirm() {
  try {
    modalApi.lock(true);

    if (validate()) {
      if (list.value.length > 0 && templateForm.saveAs) {
        await templateFormRef.value.validate();
        // 保存为场景
        await sceneAdd({
          name: templateForm.name,
          userId: userId.value,
          pageNo: pageName.value,
          data: JSON.stringify(list.value),
          isDefault: 0,
        });
        await getTemplateList();
      }

      const currList = list.value;
      // listCache.value = cloneDeep(currList);
      listCache.value = list.value;

      filterCount.value = currList.length;
      await formApi.setValues({ list: currList });
      console.log('当前筛选数据：', list.value);

      refreshExposedForm();

      resetInitialized();
      templateFormRef.value?.resetFields();
      modalApi.close();
    }
  } catch (error) {
    console.error(error);
  } finally {
    modalApi.lock(false);
  }
}

function refreshExposedForm() {
  // 汇总外露的筛选项
  _clearAllExposed();
  const exposedList = list.value.filter((v) => v.exposed);
  props.filterApi?.tableApi?.formApi.setState((prev: any) => {
    const currentSchema = prev?.schema ?? [];
    const newSchemas = exposedList.map((record, _i) => {
      return {
        component: markRaw(ConditionFilter),
        fieldName: `_${buildUUID()}_`,
        formItemClass: 'col-span-2',
        // disabledOnChangeListener: false,
        componentProps: {
          fieldNameDisabled: true,
          value: record,
          fieldList: searchFieldList.value,
          operateList: operateList.value,
        },
        defaultValue: record,
        label: record.fieldLabel,
      };
    });

    return {
      schema: [...currentSchema, ...newSchemas],
    };
  });
}

// 选择场景模板
async function handleTemplateSelect(template: SceneVO) {
  currTemplate.value = template;
  console.log(JSON.parse(template.data));
  listCache.value = JSON.parse(template.data);
  list.value = listCache.value;
  filterCount.value = listCache.value.length;
  refreshExposedForm();
  // await props.filterApi?.tableApi.query();
}

async function handleDeleteTemp(template: SceneVO) {
  await sceneRemove([template.id]);
  await getTemplateList();
}

function validate() {
  const invalid = list.value.some((item) => !item.fieldName || !item.condition);
  validateFail.value = invalid;
  return list.value.length > 0 ? !invalid : true;
}

// 添加筛选条件
async function handleAddCondition() {
  if (validate()) {
    list.value.push({
      uuid: buildUUID(),
      fieldName: null,
      condition: null,
      value: null,
      exposed: true,
    });
    await formApi.setValues({ list: list.value });
  }
}

// 删除单个筛选条件
async function handleDeleteCondition(index: number) {
  const target = list.value[index];
  if (target?.exposed) {
    // 移除外露的筛选条件
    const record = cloneDeep(target);
    record.exposed = false;
    handleExposedChange(record);
    // console.log('移除外露的筛选条件', record);
  }
  list.value.splice(index, 1);
  filterCount.value = list.value.length;
  await formApi.setValues({ list: list.value });
  console.log('移除后：', list.value);
}

function handleChange(value: any) {
  console.log('handleChange', value);
  validateFail.value = false;
}

// 清空外露在Vben基础搜索表单的筛选项
function clearAllExposed() {
  list.value = [];
  listCache.value = [];
  filterCount.value = 0;
  _clearAllExposed();
}

function _clearAllExposed() {
  props.filterApi?.tableApi?.formApi.setState((prev: any) => {
    const currentSchema = prev?.schema ?? [];
    const newSchemas = currentSchema.filter(
      (item: any) => !/^_.*_$/.test(item.fieldName),
    );
    return {
      schema: [...newSchemas],
    };
  });
}

// 外露切换
// 不做实时外露，最终确认时才一起外露
function handleExposedChange(record: any) {
  const exposed = record.exposed;
  props.filterApi?.tableApi?.formApi.setState((prev: any) => {
    const currentSchema = prev?.schema ?? [];
    const exposedSchemaFieldName = `_${record.fieldName}_`;
    const hasSameFieldItem = currentSchema.some(
      (item: any) => item.fieldName === exposedSchemaFieldName,
    );
    if (exposed) {
      if (!hasSameFieldItem) {
        const newSchema = [];
        newSchema.push({
          component: markRaw(ConditionFilter),
          fieldName: exposedSchemaFieldName,
          formItemClass: 'col-span-2',
          // disabledOnChangeListener: false,
          componentProps: {
            fieldNameDisabled: true,
            value: record,
          },
          defaultValue: record,
          label: '高级筛选',
        });

        return {
          schema: [...currentSchema, ...newSchema],
          // wrapperClass: 'grid-cols-1 md:grid-cols-2 lg:grid-cols-2 xl:grid-cols-2',
        };
      }
    } else {
      if (hasSameFieldItem) {
        const newSchemas = currentSchema.filter(
          (item: any) => item.fieldName !== exposedSchemaFieldName,
        );
        return {
          schema: [...newSchemas],
        };
      }
    }
  });
}

function getFormValues() {
  // console.log('外部调用getFormValues', list.value);
  return list.value;
}

const fieldDataList = ref<FieldVO[]>([]);
// 禁用已被选的字段名，不允许筛选重复的字段
const searchFieldList = computed(() => {
  return fieldDataList.value.map((item) => {
    item.disabled = list.value.some((v) => v.fieldName === item.fieldName);
    return item;
  });
});
const operateList = ref<DictData[]>([]);

// 场景列表
const templateList = ref<SceneVO[]>([]);

async function getTemplateList() {
  const scenes = await sceneList({
    userId: userId.value,
    pageNo: pageName.value,
  });
  // console.log('场景列表：', scenes);
  templateList.value = scenes;
}

onMounted(async () => {
  console.log('当前页面路由地址名称：', pageName.value);

  // 根据页面编号查询是否配置高级筛选
  const fields = await fieldList({ pageNo: pageName.value });
  // console.log('高级筛选字段信息：', fields);
  if (fields?.length > 0) {
    operateList.value = await dictDataInfo(DictEnum.QUERY_OPERATE_TYPE);
    await getTemplateList();
    fieldDataList.value = fields;
    show.value = true;
  }
});

defineExpose({
  getFormValues,
  clearAllExposed,
});
</script>

<template>
  <div v-if="show" class="mb-[12px] flex justify-end">
    <div v-if="templateList.length > 0">
      <Button
        v-for="scene in templateList"
        :key="scene.id"
        type="dashed"
        class="mr-[8px]"
        @click="handleTemplateSelect(scene)"
      >
        {{ scene.name }}
        <Popconfirm
          :get-popup-container="getPopupContainer"
          title="您确定要删除这个筛选场景吗？"
          placement="left"
          class="z-100"
          @confirm.stop="handleDeleteTemp(scene)"
        >
          <Tooltip title="删除场景">
            <VbenIcon
              icon="pajamas:remove"
              class="mb-[3px] ml-[5px] inline-block"
              @click.stop=""
            />
          </Tooltip>
        </Popconfirm>
      </Button>
    </div>
    <DropdownButton placement="bottomRight" @click="handleFilterClick">
      <template #overlay>
        <Menu v-if="templateList.length > 0">
          <MenuItem
            v-for="temp in templateList"
            :key="temp.id"
            @click="handleTemplateSelect(temp)"
          >
            <!--<VbenIcon icon="tabler:filter-star" class="mb-[3px] inline-block" />-->
            {{ temp.name }}
            <Popconfirm
              :get-popup-container="getPopupContainer"
              title="您确定要删除这个筛选场景吗？"
              placement="left"
              class="z-100"
              @confirm.stop="handleDeleteTemp(temp)"
            >
              <Tooltip title="删除场景">
                <VbenIcon
                  icon="pajamas:remove"
                  class="mb-[3px] inline-block"
                  @click.stop=""
                />
              </Tooltip>
            </Popconfirm>
          </MenuItem>
        </Menu>
      </template>
      <template #icon>
        <Badge :count="showBadge ? filterCount : 0" :offset="[-96, 0]">
          <VbenIcon icon="tabler:filter-2-search" />
        </Badge>
      </template>
      高级筛选
    </DropdownButton>

    <!--<Badge :count="filterCount">-->
    <!--  <Button @click="handleFilterClick">-->
    <!--    <template #icon>-->
    <!--      <VbenIcon icon="tabler:filter-2-search" class="mb-[5px]" />-->
    <!--    </template>-->
    <!--    高级筛选-->
    <!--  </Button>-->
    <!--</Badge>-->

    <BasicModal :title="title" class="w-[950px]">
      <BasicForm />
      <div class="p-2">
        <!--<BasicForm />-->
        <div v-if="list.length > 0">
          <ConditionFilter
            v-for="(_item, i) in list"
            :key="_item.uuid"
            v-model:value="list[i]"
            :field-list="searchFieldList"
            :operate-list="operateList"
            class="mb-[12px]"
            @change="handleChange"
          >
            <template #label>
              <div
                class="mr-2 flex flex-shrink-0 items-center justify-end text-sm font-medium leading-6"
                style="width: 90px"
              >
                筛选条件{{ i + 1 }}：
              </div>
            </template>
            <template #append>
              <div>
                <Popconfirm
                  title="您确定要删除这一条数据吗？"
                  placement="left"
                  @confirm="handleDeleteCondition(i)"
                >
                  <Tooltip title="删除条件">
                    <Button
                      type="dashed"
                      shape="circle"
                      :icon="h(CloseOutlined)"
                    />
                  </Tooltip>
                </Popconfirm>
              </div>
              <!--<div v-if="list[i]">-->
              <!--  <Checkbox-->
              <!--    v-model:checked="list[i].exposed"-->
              <!--    :disabled="!list[i].fieldName"-->
              <!--  >-->
              <!--    外露-->
              <!--  </Checkbox>-->
              <!--</div>-->
            </template>
          </ConditionFilter>
        </div>
        <Empty
          v-else
          description="暂无筛选条件"
          :image="Empty.PRESENTED_IMAGE_SIMPLE"
        />
        <Alert
          v-if="validateFail"
          banner
          show-icon
          type="error"
          message="请完善筛选条件"
        />
        <div class="mt-[10px]">
          <Button type="dashed" @click.stop="handleAddCondition">
            <template #icon>
              <VbenIcon icon="mingcute:add-fill" />
            </template>
            添加筛选条件
          </Button>
        </div>
      </div>
      <template #prepend-footer>
        <div v-if="list.length > 0" class="flex items-center">
          <Form
            ref="templateFormRef"
            :model="templateForm"
            layout="inline"
            :rules="templateFormRules"
          >
            <FormItem name="saveAs">
              <Checkbox v-model:checked="templateForm.saveAs">
                保存为场景
              </Checkbox>
            </FormItem>
            <FormItem v-if="templateForm.saveAs" name="name">
              <Input
                v-model:value="templateForm.name"
                placeholder="自定义场景名称"
                show-count
                :maxlength="10"
              />
            </FormItem>
          </Form>
        </div>
      </template>
    </BasicModal>
  </div>
</template>
